package w83b.Thread;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import n38a.exe.N38APISesion;

import org.w3c.dom.Document;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import w83b.iLote4.stubs.W83bNSHFFacadeWS;
import w83b.w83bBeans.W83bNotificacionesBean;
import w83b.w83bBeans.W83bUsuarioBean;
import w83b.w83bDAO.W83bNotificacionesDAO;
import w83b.w83bManager.W83bEjGvDocumento;
import w83b.w83bManager.W83bWebServiceutils;
import w83b.w83bUtilidadesComunes.W83bBase64;
import w83b.w83bUtilidadesComunes.W83bClsConstantes;
import w83b.w83bUtilidadesComunes.W83bClsTrazas;
import w83b.w83bUtilidadesComunes.W83bInformacionProcedimiento;
import w83b.w83bUtilidadesComunes.W83bProperties;
import w83b.w83bUtilidadesComunes.W83bSolicitudPreaviso;

import com.ejie.y31.factory.Y31JanoServiceAbstractFactory;
import com.ejie.y31.service.Y31JanoService;
import com.ejie.y31.vo.Y31AttachmentBean;



public class W83bNotificacionThread extends Thread {
	ArrayList listaSindicatos;
	W83bInformacionProcedimiento info;
	W83bUsuarioBean sindicato;
	W83bNotificacionesBean infoNotificacion;
	W83bSolicitudPreaviso preaviso;
	String direccionEnvio;
	String nombreFichero;
	String documentoImportadoOriginal;
	String idioma;


// Constructor para almacenar nuestro nombre
// y el retardo
public W83bNotificacionThread( ArrayList listaSindicatos, W83bInformacionProcedimiento info, W83bSolicitudPreaviso preaviso,W83bNotificacionesBean infoNotificacion,String direccionEnvio,  String nombreFichero, String documentoImportadoOriginal, String idioma) {
	this.listaSindicatos=listaSindicatos;
	this.info=info;
	this.preaviso=preaviso;
	this.infoNotificacion=infoNotificacion;
	this.direccionEnvio=direccionEnvio;
	this.nombreFichero=nombreFichero;
	this.documentoImportadoOriginal=documentoImportadoOriginal;
	this.idioma=idioma;
    }



public static String getTokenXLNets (String idAplic){
  String token = null;
 
  try {
    N38APISesion miAPISesion = new N38APISesion();
    Document miSesion;
    miSesion=miAPISesion.n38APISesionCrearApp(idAplic);
    token = DOM2String(miSesion);

  } catch (Exception e){
	  
	  
   W83bClsTrazas.trazaError(null, "W83bNotificacionThread->getTokenXLNets: Excepcion creando el token de aplicacion",null);
   e.printStackTrace();
  }
 
  return token;
}

/**
 * Lee un fichero y devuelve el contenido
 * @param elFichero el nombre del fichero
 * @param codificar indica si ha de codificarse el contenido 
 * @return el contenido
 */
private static String leerFichero(String elFichero, boolean codificar){
	String cadenaSesion= "";
	try {
		File laSesion= new File(elFichero);
		
		InputStream is = new FileInputStream(laSesion);
	    
        long length = laSesion.length();
	    
        // Create the byte array to hold the data
        byte[] bytes = new byte[(int) length];
	    
	    // Read in the bytes
	    int offset = 0;
	    int numRead = 0;
	    while (offset < bytes.length
	    		&& (numRead=is.read(bytes, offset, bytes.length - offset)) >= 0) {
	    	offset += numRead;
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("No se ha podido leer " + elFichero);
        }

        // Close the input stream and return bytes
        is.close();

        BASE64Encoder encoder = new BASE64Encoder();

        if (codificar) {
            cadenaSesion = encoder.encode(bytes);
        } else {
            cadenaSesion = new String(bytes);
        }

	} catch (Exception e) {
		W83bClsTrazas.trazaError(null, "W83bNotificacionThread.leerFichero->EXCEPTION",null);
	}

	return cadenaSesion;
}


public static String DOM2String(Document doc)
{
	TransformerFactory transformerFactory =TransformerFactory.newInstance();
	Transformer transformer = null;
	try{
		transformer = transformerFactory.newTransformer();
	}catch (javax.xml.transform.TransformerConfigurationException error){
		return null;
	}
	 
	Source source = new DOMSource(doc);
	 
	StringWriter writer = new StringWriter();
	Result result = new StreamResult(writer);
	try{
		transformer.transform(source,result);
	}catch (javax.xml.transform.TransformerException error){
		return null;
	}
	 
	String s = writer.toString();
	return s;//NOPMD
}


// El metodo run() es similar al main(), pero para
// threads. Cuando run() termina el thread muere
public void run() {

    try {
    	
    	W83bClsTrazas.trazaDebug(null," ---- EMPIEZA EL THREAD ----");
        N38APISesion miAPISesion = new N38APISesion();
        Document miSesion=miAPISesion.n38APISesionCrearApp("w83b");
        infoNotificacion.setSessionTokenXLNET(DOM2String(miSesion));
        
        W83bClsTrazas.trazaDebug(null," ---- coge el token: " + miSesion);
    	
    	
    	
    	String firma="";
    	boolean error=false;
        for(int i=0;i<listaSindicatos.size();i++){
        	
    		String rutaDoc = "/r02g/w83b/"+nombreFichero;
    		W83bClsTrazas.trazaDebug(null,"rutaDoc:"+rutaDoc);
    		
    		 //PIF
        	InputStream is = new ByteArrayInputStream(documentoImportadoOriginal.getBytes());
        	W83bClsTrazas.trazaDebug(null,"documentoImportadoOriginal: "+documentoImportadoOriginal);
        	W83bClsTrazas.trazaDebug(null,"is:"+is );
        	
        	Y31JanoService service = Y31JanoServiceAbstractFactory.getInstance();
        	W83bClsTrazas.trazaDebug(null,"despues del service");
        	
        	Y31AttachmentBean rdo = service.put(miSesion, is, rutaDoc, false, new Long (3600));
        	W83bClsTrazas.trazaDebug(null,"despues del put");
        	
        	String rutaFichero = rdo.getFilePath();
        	W83bClsTrazas.trazaDebug(null,"rutaFichero: "+rutaFichero );
    	

        	
        	sindicato = (W83bUsuarioBean) listaSindicatos.get(i);
        	W83bClsTrazas.trazaDebug(null,"sindicato "+sindicato.getDniUsuario());
        	
 
//*****************************************INICIO GENERAR NOTIFICACION********************************************//
        	//Creamos el notificación Task
        	String notificationCreateTask = W83bWebServiceutils.generarNotificationCreateTask(info.getProcedureId(), info, infoNotificacion, sindicato,preaviso,direccionEnvio, rutaFichero, idioma);
        	W83bClsTrazas.trazaDebug(null,"Se ha obtenido el Notificacion Task");
        	
        	//Llamada a WS para crear la notificación
        	String resultadoNotificacion = W83bEjGvDocumento.generarNotificacion(infoNotificacion.getSessionTokenXLNET(), notificationCreateTask);
        	W83bClsTrazas.trazaDebug(null," resultadoNotificacion ---->" +resultadoNotificacion);
        	
        	//Pasamos a base64 la notificación
        	String result = W83bBase64.decodeToString(resultadoNotificacion);
        	W83bClsTrazas.trazaDebug(null,"Resultado generar notificacion decodificado---->" +result);
//**********************************FIN GENERAR NOTIFICACION********************************************//
        	
        	

//**********************************INICIO FIRMAR NOTIFICACION****************************************************************//
        	if("".equals(result)){
        		W83bClsTrazas.trazaDebug(null,"Resultado generar notificacion vacio ERROR");
        		//Si esta vacía la notificación error
        		error=true;
        	}else{

					//firmar notificacion.
        		W83bClsTrazas.trazaDebug(null,"Intentando Obtener la firma simple para la notificación");
					
					//Recuperamos la certificación para firmar la notificación
					String certificateId= "";
					if(infoNotificacion.getTerritorioUsuarioXLNET().equals(W83bClsConstantes.CONSTANTE_BIZKAIA)){
						certificateId= W83bProperties.getProperty("w83b", "certificateId.bizkaia");
					}else if(infoNotificacion.getTerritorioUsuarioXLNET().equals(W83bClsConstantes.CONSTANTE_GIPUZKOA)){
						certificateId= W83bProperties.getProperty("w83b", "certificateId.gipuzkoa");
					}else if(infoNotificacion.getTerritorioUsuarioXLNET().equals(W83bClsConstantes.CONSTANTE_ALAVA)){
						certificateId= W83bProperties.getProperty("w83b", "certificateId.araba");
					}else{
						certificateId= W83bProperties.getProperty("w83b", "certificateId.general");
					}
					W83bClsTrazas.trazaDebug(null,"firmar notificacion. Territorio usuario: "+infoNotificacion.getTerritorioUsuarioXLNET());
					W83bClsTrazas.trazaDebug(null,"Certificado ---->" +certificateId);
					
					
					

					
					BASE64Decoder decoder = new BASE64Decoder();

					String ejgvNotificacionB64preparado = new String(
							decoder.decodeBuffer(resultadoNotificacion));

					
					
					//LLAMADA A WS para obtener la firma
					W83bNSHFFacadeWS NSHFFacade = new W83bNSHFFacadeWS();
					firma=NSHFFacade.createAdESSignature(infoNotificacion.getSessionTokenXLNET(), certificateId, ejgvNotificacionB64preparado);
					
					byte[] firmaByte = firma.getBytes("ISO-8859-1");
					W83bClsTrazas.trazaDebug(null,"Resultado generar firmar---->" +firma);
//*********************************************************FIN FIRMAR NOTIFICACION***********************************************************************//	       	
        	
//*****************************************************INICIO PUBLICAR NOTIFICACION******************************************************************//						
					if("".equals(firma)){
						W83bClsTrazas.trazaDebug(null,"No hay firma notificacion ERROR");
						//No hay firma error
						error=true;
					}else{
						//Publicamos la notificación
						String idNotificacion=W83bEjGvDocumento.publicarNotificacion(infoNotificacion.getSessionTokenXLNET(),resultadoNotificacion,new String(firmaByte));//NOPMD
						W83bClsTrazas.trazaDebug(null,"idNotificacion:" +idNotificacion);
						if (idNotificacion==null || "".equals(idNotificacion)){
							W83bClsTrazas.trazaDebug(null,"No se ha publicado la notificacion ERROR");
							error=true;
						}
					}
				//}
        	}
        	
//*****************************************FIN PUBLICAR NOTIFICACION******************************************************************//	
					
        	if(error){
        		W83bClsTrazas.trazaDebug(null, "HA HABIDO ALGÚN ERROR EN LA NOTIFICACIÓN");
            	//guardar en la base de datos.
        		W83bClsTrazas.trazaDebug(null,"guardar en la base de datos"+((W83bUsuarioBean) listaSindicatos.get(i)).getNombreUsuario()+""+i);
            	
            	int result2 = W83bNotificacionesDAO.W83bInsertarNotificaciones(infoNotificacion,direccionEnvio,((W83bUsuarioBean) listaSindicatos.get(i)).getOrganizacion());
            	if (result2==0){
            		W83bClsTrazas.trazaDebug(null,"error al insertar la notificacion");
            	}
            }
        	
        	W83bClsTrazas.trazaDebug(null," ---- FINALIZA EL THREAD ----");
        	
        	
        }

        
    } catch( InterruptedException e ) {
        ;
    } catch (Exception e1){
        ;
    }

    // Ahora imprimimos el nombre
    }
}
